package com.mediacloud.app.newsmodule.activity

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.media.AudioManager
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.baidu.location.BDLocation
import com.baidu.speech.EventListener
import com.baidu.speech.EventManager
import com.baidu.speech.EventManagerFactory
import com.baidu.speech.asr.SpeechConstant
import com.baidu.tts.client.SpeechSynthesizer
import com.baidu.tts.client.SpeechSynthesizerListener
import com.baidu.tts.client.TtsMode
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.SPUtils
import com.eventTrack.TXReportManager
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.interfaces.DraweeController
import com.facebook.drawee.view.SimpleDraweeView
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.hjq.shape.view.ShapeView
import com.king.zxing.util.PermissionUtils
import com.mediacloud.app.assembly.util.toastCenter
import com.mediacloud.app.model.ActionDateActive
import com.mediacloud.app.model.ActionEditionActive
import com.mediacloud.app.model.ActionPartActive
import com.mediacloud.app.model.AiAsstantWekeup
import com.mediacloud.app.model.activity.BaseBackActivity
import com.mediacloud.app.model.adaptor.BaseAdapter
import com.mediacloud.app.model.dialog.AiAssistantAdapter
import com.mediacloud.app.model.dialog.AiAssistantData
import com.mediacloud.app.model.dialog.AiAssistantDialog.Companion.LEFT_CHAT
import com.mediacloud.app.model.dialog.AiAssistantDialog.Companion.LEFT_CHAT_ARTICLE
import com.mediacloud.app.model.dialog.AiAssistantDialog.Companion.LEFT_CHAT_VOICE
import com.mediacloud.app.model.dialog.AiAssistantDialog.Companion.LEFT_FIRST
import com.mediacloud.app.model.dialog.AiAssistantDialog.Companion.RIGHT_CHAT
import com.mediacloud.app.model.dialog.PaperDetailBean
import com.mediacloud.app.model.eventbus.event.EmptyEvent
import com.mediacloud.app.model.eventbus.event.IntentAppHomeEvent
import com.mediacloud.app.model.news.ArticleItem
import com.mediacloud.app.model.utils.AnimUtils
import com.mediacloud.app.model.utils.WekaupManager
import com.mediacloud.app.model.wakeup.*
import com.mediacloud.app.newsmodule.R
import com.mediacloud.app.newsmodule.fragment.baoliao.api.AiAssistantApi
import com.mediacloud.app.newsmodule.utils.ToastUtil
import com.mediacloud.app.reslib.enums.AppFactoryGlobalConfig
import com.mediacloud.app.reslib.enums.XKey
import com.mediacloud.app.reslib.util.DataInvokeUtil
import com.mediacloud.app.reslib.util.ModuleReferenceConfig
import com.mediacloud.app.sb.sbplayer.utils.PlayerTools
import com.mediacloud.app.user.model.UserInfo
import com.mediacloud.app.user.utils.DeviceInfo
import com.mediacloud.app.user.utils.RxUtils
import com.mediacloud.location.LocationKit
import com.tencent.mmkv.MMKV
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONException
import org.json.JSONObject
import tv.danmaku.ijk.media.player.IjkMediaPlayer
import java.io.IOException

/**
 * Date:2022/7/7
 * Author:kgf
 * 全屏机器人java转kotlin，转换完成后要注意某些方法的参数要可为空(也就是加问号)
 */
class AIAssistantActivity : BaseBackActivity(), View.OnClickListener, EventListener {

    private var sendMsg: TextView? = null
    private var topView: View? = null
    private var edMsg: EditText? = null
    private var input_tx: LinearLayout? = null
    private var input_content: TextView? = null
    private var recyclerView: RecyclerView? = null
    private var mAdapter: AiAssistantAdapter? = null
    private var active: String? = null
    private var search: String? = null
    private var message: String? = null
    private var readSize = 0
    private var aid: String? = null
    private var mIvMic: SimpleDraweeView? = null
    private var mIvMicLong: SimpleDraweeView? = null
    private var shapeViewDot: ShapeView? = null
    private var asr: EventManager? = null
    private var mSpeechSynthesizer: SpeechSynthesizer? = null
    private var bottom: ConstraintLayout? = null
    private var mAudioManager: AudioManager? = null
    private var mediaPlayer: IjkMediaPlayer? = null
    private var url: String? = null
    private var answerType: String? = null
    private var audioFlag = true
    private val map = mutableMapOf<String, Any>()
    private var checkDestroy: Boolean = false

    override fun getLayoutResID(): Int {
        return R.layout.activity_ai_assistant_layout
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initView()
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
        //dataList = new ArrayList<>()
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        val tmgr = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
        tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
        setTitle("AI助手-1927")
        mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
        initTTs()
        //setAnim()
    }

    private fun setAnim() {
        AnimUtils.setAiAnim(
            findViewById(R.id.iv_ai_robot),
            findViewById(R.id.iv_ai_robot_left),
            findViewById(R.id.iv_ai_center),
            this,
            findViewById(R.id.endView),
            null,
            null
        )
    }

    private val mPhoneStateListener: PhoneStateListener = object : PhoneStateListener() {
        override fun onCallStateChanged(state: Int, phoneNumber: String?) {
            super.onCallStateChanged(state, phoneNumber)
            if (state == TelephonyManager.CALL_STATE_RINGING || state == TelephonyManager.CALL_STATE_OFFHOOK) {
                if (mediaPlayer != null) {
                    mediaPlayer?.pause()
                }
            }
            // else if (state == TelephonyManager.CALL_STATE_IDLE) {
//                try {
//                    Log.e("OPIO", "挂电话");
//                    if (mediaPlayer != null) {
//                        mediaPlayer.setVolume(0f, 0f);
//                        root_view.postDelayed(() -> mediaPlayer.start(), 1000);
//                    }
//                } catch (Exception e) {
//                }
//            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    fun setDataList(data: ArrayList<AiAssistantData>) {
        //ArrayList<AiAssistantData> data = getIntent().getParcelableArrayListExtra("data");
        if (data.size > 0) {
            mAdapter?.addListData(data)
        } else {
            initDialogue()
        }
    }

    /**
     * 基于SDK集成2.2 发送开始事件
     * 点击开始按钮
     * 测试参数填在这里 discern
     */
    private fun startDiscern(isListener: Boolean) {
        stopAudio()
        val params = AuthUtil.getInstance().param
        val event = SpeechConstant.ASR_START //替换成测试的event

        // 基于SDK集成2.1 设置识别参数
        params[SpeechConstant.DECODER] = false
        //        params.put(SpeechConstant.DISABLE_PUNCTUATION, true);  //禁用标点符号

        // 请先使用如‘在线识别’界面测试和生成识别参数。 params同ActivityRecog类中myRecognizer.start(params);
        // 复制此段可以自动检测错误
        AutoCheck(
            applicationContext, @SuppressLint("HandlerLeak")
            object : Handler() {
                override fun handleMessage(msg: Message) {
                    if (msg.what == 100) {
                        val autoCheck = msg.obj as AutoCheck
                        synchronized(autoCheck) {
                            val message =
                                autoCheck.obtainErrorMessage() // autoCheck.obtainAllMessage();
                            printLog(message.trim())
                        }
                    }
                }
            }, false
        ).checkAsr(params)
        val json = JSONObject(params).toString() // 这里可以替换成你需要测试的json
        if (isListener) {
            asr?.send(event, json, null, 0, 0)
        } else {
            WekaupManager.getInstance().startWekeup()
        }
        showDiscernLayout(isListener)
        printLog("输入参数：$json")
    }

    private fun showDiscernLayout(isListener: Boolean) {
        if (bottom?.visibility == View.GONE) {
            input_tx?.visibility = View.VISIBLE
            input_content?.text = ""
            edMsg?.setText("")
            if (isListener) {
                mIvMic?.visibility = View.GONE
                mIvMicLong?.visibility = View.VISIBLE
                shapeViewDot?.visibility = View.VISIBLE
                input_content?.hint = "倾听中......"
            } else {
                mIvMic?.visibility = View.VISIBLE
                mIvMicLong?.visibility = View.GONE
                shapeViewDot?.visibility = View.GONE
                input_content?.hint = ""
            }
        } else {
            input_tx?.visibility = View.GONE
        }
    }

    private fun printLog(text: String) {
        var text: String? = text
        val logTime = true
        if (logTime) {
            text += "  ;time=" + System.currentTimeMillis()
        }
    }

    override fun onEvent(
        name: String,
        params: String?,
        data: ByteArray?,
        offset: Int,
        length: Int
    ) {
        var logTxt = "name: $name"
        if (name == SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL) {
            // 识别相关的结果都在这里
            if (params == null || params.isEmpty()) {
                return
            }
            if (params.contains("\"partial_result\"")) {
                // 一句话的临时识别结果
                try {
                    val jsonObject = JSONObject(params)
                    edMsg?.setText(jsonObject.getString("best_result"))
                    input_content?.text = jsonObject.getString("best_result")
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            } else if (params.contains("\"final_result\"")) {
                // 一句话的最终识别结果
                logTxt += ", 最终识别结果：$params"
//                mHandler.sendEmptyMessageDelayed(0, 1500)
//                stopAudio()
//                stopDiscern(false)
                var replace: String
                try {
                    val jsonObject = JSONObject(params)
                    replace = jsonObject.getString("best_result").replace("。", "")
                    if (replace.contains("18大")) {
                        replace = replace.replace("18大", "十八大")
                    } else if (replace.contains("19大")) {
                        replace = replace.replace("19大", "十九大")
                    } else if (replace.contains("20大")) {
                        replace = replace.replace("20大", "二十大")
                    } else if (replace.contains("歼二零")) {
                        replace = replace.replace("歼二零", "歼20")
                    } else if (replace.contains("运二零")) {
                        replace = replace.replace("运二零", "运20")
                    } else if (replace.contains("歼十五")) {
                        replace = replace.replace("歼十五", "歼15")
                    } else if (replace.contains("歼十六")) {
                        replace = replace.replace("歼十六", "歼16")
                    } else if (replace.contains("地图，新闻")) {
                        replace = replace.replace("地图，新闻", "地图新闻")
                    }
                    edMsg?.setText(replace)
                    input_content?.text = replace
                    TXReportManager.getInstance().app_jhapp_ai_assistant_use("语音", replace)
                    showDiscernLayout(false)
                    sendMessage(replace)
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }
        } else {
            // 识别开始，结束，音量，音频数据回调
            if (params != null && params.isNotEmpty()) {
                logTxt += " ;params :$params"
                val jsonObject = JSONObject(params)
                val sub_error = jsonObject.optInt("sub_error")
                if (sub_error >= 10000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"其它错误")
                    showDiscernLayout(false)
                } else if (sub_error >= 9000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"缺少权限")
                    showDiscernLayout(false)
                } else if (sub_error >= 8000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"识别超时")
                    showDiscernLayout(false)
                } else if (sub_error >= 7000) {
                    if (!checkDestroy) {
//                        com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"没有识别结果")
                    }
                    showDiscernLayout(false)
                } else if (sub_error >= 6000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"识别超时")
                    showDiscernLayout(false)
                } else if (sub_error >= 5000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"客户端调用错误")
                    showDiscernLayout(false)
                } else if (sub_error >= 4000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"协议错误")
                    showDiscernLayout(false)
                } else if (sub_error >= 3000) {
                    if (sub_error == 3101) {
                        com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"长时间未检测到人说话，请重新识别")
                    } else if (sub_error == 3102) {
                        com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"检测到人说话，但语音过短")
                    } else {
                        com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"音频错误")
                    }
                    showDiscernLayout(false)
                } else if (sub_error >= 2000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"网络异常，请检查网络")
                    showDiscernLayout(false)
                } else if (sub_error >= 1000) {
                    com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"网络异常，请检查网络")
                    showDiscernLayout(false)
                }

            }
        }
        if (TextUtils.isEmpty(input_content?.text.toString())) {
            shapeViewDot?.shapeDrawableBuilder?.setSolidColor(-0x661be2e3)
                ?.intoBackground() // 注意：最后需要调用一下 intoBackground 方法才能生效
        } else {
            shapeViewDot?.shapeDrawableBuilder?.setSolidColor(-0x1be2e3)
                ?.intoBackground() // 注意：最后需要调用一下 intoBackground 方法才能生效
        }
        printLog(logTxt)
    }

    private fun initView() {
        mIvMic = findViewById(R.id.mic_img)
        mIvMicLong = findViewById(R.id.mic_img_log)
        shapeViewDot = findViewById(R.id.shape_view_ai_red_dot)
        val mIvKeyBoard = findViewById<ImageView>(R.id.iv_key_board)
        input_tx = findViewById(R.id.input_tx)
        input_content = findViewById(R.id.input_content)
        val mBtnVoice = findViewById<View>(R.id.btn_voice)
        topView = findViewById(R.id.topview)
        sendMsg = findViewById(R.id.sendMsg)
        bottom = findViewById(R.id.bottom)
        edMsg = findViewById(R.id.edMsg)
        recyclerView = findViewById(R.id.recyclerView)
        mBtnVoice.setOnClickListener(this)
        mIvKeyBoard.setOnClickListener(this)
        mIvMic?.setOnClickListener(this)
        mIvMicLong?.setOnClickListener(this)
        sendMsg?.setOnClickListener(this)

        val userInfo = UserInfo.getUserInfo(this)
        map["userId"] = userInfo.userid ?: ""
        map["nickName"] = userInfo.nickname ?: ""
        map["name"] = userInfo.username ?: ""
        map["mobile"] = userInfo.mobile ?: ""

        if (XXPermissions.isGranted(this, Permission.ACCESS_FINE_LOCATION)) {
            LocationKit.getLocation(this, object : LocationKit.LocationListener {
                override fun onLocationFail(failMessage: String?) {
                    map["address"] = ""
                    initDialogue()
                }

                override fun onLocationSuccess(location: BDLocation) {
                    map["address"] = location.city ?: ""
                    initDialogue()
                }
            }, 60000)
        } else {
            if (userInfo.isLogin) {
                DataInvokeUtil.getZiMeiTiApi()
                    .getSelfMediaNumberInfoNew(userInfo.spider_userid, userInfo.access_token)
                    .compose(RxUtils.schedulersTransformer())
                    .subscribe(object : Observer<JSONObject> {
                        override fun onComplete() {

                        }

                        override fun onSubscribe(d: Disposable) {

                        }

                        override fun onNext(t: JSONObject) {
                            val data = t.optJSONObject("data")
                            if (data != null) {
                                val meta = data.optJSONObject("meta")
                                if (meta != null) {
                                    map["address"] = meta.optString("ipAddress") ?: ""
                                    initDialogue()
                                }
                            }
                        }

                        override fun onError(e: Throwable) {
                            map["address"] = ""
                            initDialogue()
                        }
                    })
            } else {
                map["address"] = ""
            }
        }

        val uri = resourceIdToUri(this, R.drawable.ai_listener_long)
        val controller: DraweeController = Fresco.newDraweeControllerBuilder()
            .setUri(uri)
            .setAutoPlayAnimations(true)
            .build()
        mIvMicLong?.controller = controller

        val micUri = resourceIdToUri(this, R.drawable.ai_listener_circle)
        val micController: DraweeController = Fresco.newDraweeControllerBuilder()
            .setUri(micUri)
            .setAutoPlayAnimations(true)
            .build()
        mIvMic?.controller = micController

        if (TextUtils.isEmpty(input_content?.text.toString())) {
            shapeViewDot?.shapeDrawableBuilder?.setSolidColor(-0x661be2e3)
                ?.intoBackground() // 注意：最后需要调用一下 intoBackground 方法才能生效
        } else {
            shapeViewDot?.shapeDrawableBuilder?.setSolidColor(-0x1be2e3)
                ?.intoBackground() // 注意：最后需要调用一下 intoBackground 方法才能生效
        }

        mAdapter = AiAssistantAdapter(this)
        recyclerView?.layoutManager = LinearLayoutManager(this)
        recyclerView?.adapter = mAdapter
        mAdapter?.itemClickListener = object : BaseAdapter.OnItemClickListener<AiAssistantData> {
            override fun onItemClick(
                clickView: View,
                position: Int,
                data: AiAssistantData?,
                adapter: BaseAdapter<AiAssistantData>
            ) {
                if (data != null) {
                    if (data.type == LEFT_CHAT_VOICE) {
                        stopAudio()
                        if (data.voice != null) {
                            if (data.voice.url != null) {
                                setData(data.voice.url)
                            }
                        }
                    }
                }
            }
        }
    }

    private fun initDialogue() {
        AiAssistantApi.getSpiderCmsApiJson(this)
            .startASession(DeviceInfo.getDeviceInfo(this).deviceInfo4Server.device_flag, map)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<JSONObject> {
                override fun onSubscribe(d: Disposable) {}
                override fun onNext(jsonObject: JSONObject) {
                    val data = jsonObject.optJSONObject("data") ?: return
                    val helloWord = data.optString("helloWord")
                    if (TextUtils.isEmpty(helloWord)) {
                        toastCenter(this@AIAssistantActivity, "请稍候重试")
                    }
                    val aiAssistantData = AiAssistantData()
                    aiAssistantData.msg = helloWord
                    aiAssistantData.type = LEFT_FIRST
                    mAdapter?.addData(aiAssistantData)
                    message = helloWord
                }

                override fun onError(e: Throwable) {
                    Log.e("onError", "------:" + e.message)
                    toastCenter(this@AIAssistantActivity, "请稍候重试")
                }

                override fun onComplete() {}
            })
    }

    override fun onStart() {
        super.onStart()
        MMKV.defaultMMKV().putBoolean(XKey.FULL_SCREEN, true)
    }

    override fun onStop() {
        super.onStop()
        MMKV.defaultMMKV().putBoolean(XKey.FULL_SCREEN, false)
    }

    private fun resourceIdToUri(context: Context, resourceId: Int): Uri {
        return Uri.parse(
            "android.resource://" + context.packageName
                    + "/" + resourceId
        )
    }

    /**
     * desc:机器人播放完毕继续识别
     *
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun speakFinishActivity(event: EmptyEvent?) {
        startDiscern(TextUtils.isEmpty(aid))
    }

    //如果当前页面呼出机器人就让他监听
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun callAiActivity(event: AiAsstantWekeup) {
        if (XKey.FULL_SCREEN == event.action) {
            startDiscern(true)
        }
    }

    private fun initVoiceBox() {
        val discernFlag = intent.getBooleanExtra("discernFlag", false)
        if (discernFlag) {
            if (PermissionUtils.checkPermission(
                    this,
                    Manifest.permission.RECORD_AUDIO
                )
            ) {
                startDiscern(true)
                input_tx?.visibility = View.VISIBLE
                bottom?.visibility = View.GONE
            } else {
                com.utils.ToastUtil.showToastCenter(this@AIAssistantActivity,"请打开麦克风权限")
            }
        } else {
            cancelDiscern(false)
            stopDiscern(false)
            input_tx?.visibility = View.GONE
            bottom?.visibility = View.VISIBLE
        }
    }

    /**
     * 注意此处为了说明流程，故意在UI线程中调用。
     * 实际集成中，该方法一定在新线程中调用，并且该线程不能结束。具体可以参考NonBlockSyntherizer的写法
     */
    private fun initTTs() {
        asr = EventManagerFactory.create(this, "asr")
        // 基于sdk集成1.3 注册自己的输出事件类
        asr?.registerListener(this) //  EventListener 中 onEvent方法
        // 日志更新在UI中，可以换成MessageListener，在logcat中查看日志
        val listener: SpeechSynthesizerListener = UiMessageListener(Handler())

        // 1. 获取实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance()
        mSpeechSynthesizer?.setContext(this)

        // 2. 设置listener
        mSpeechSynthesizer?.setSpeechSynthesizerListener(listener)

        // 3. 设置appId，appKey.secretKey
        mSpeechSynthesizer?.setAppId(AuthUtil.getInstance().appId)
        mSpeechSynthesizer?.setApiKey(AuthUtil.getInstance().ak, AuthUtil.getInstance().sk)

        // 4. 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人： 0 普通女声（默认） 1 普通男声  3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        val voice_type = SPUtils.getInstance().getInt("voice_type", 4)
        mSpeechSynthesizer?.setParam(SpeechSynthesizer.PARAM_SPEAKER, voice_type.toString())
        // 设置合成的音量，0-15 ，默认 5
        mSpeechSynthesizer?.setParam(SpeechSynthesizer.PARAM_VOLUME, "9")
        // 设置合成的语速，0-15 ，默认 5
        mSpeechSynthesizer?.setParam(SpeechSynthesizer.PARAM_SPEED, "5")
        // 设置合成的语调，0-15 ，默认 5
        mSpeechSynthesizer?.setParam(SpeechSynthesizer.PARAM_PITCH, "5")

        // mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL); // 调整音频输出

        // x. 额外 ： 自动so文件是否复制正确及上面设置的参数
        val params: Map<String, String> = HashMap()
        // 复制下上面的 mSpeechSynthesizer.setParam参数

        // 检测参数，通过一次后可以去除，出问题再打开debug
        val initConfig = InitConfig(
            AuthUtil.getInstance().appId,
            AuthUtil.getInstance().ak,
            AuthUtil.getInstance().sk,
            TtsMode.ONLINE,
            params,
            listener
        )
        AutoTTSCheck.getInstance(applicationContext).check(initConfig, @SuppressLint("HandlerLeak")
        object : Handler() {
            /**
             * 开新线程检查，成功后回调
             */
            override fun handleMessage(msg: Message) {
                if (msg.what == 100) {
                    val autoCheck = msg.obj as AutoTTSCheck
                    synchronized(autoCheck) { val message = autoCheck.obtainDebugMessage() }
                }
            }
        })
        // 5. 初始化
        mSpeechSynthesizer?.initTts(TtsMode.ONLINE)
        initVoiceBox()
    }

    private fun speak() {
        if (mSpeechSynthesizer == null) {
            return
        }
        var speakMessage: String? = ""
        if (readSize > 0 && readSize < message!!.length) {
            speakMessage = message!!.substring(0, readSize)
        } else if (message!!.length <= 60) {
            speakMessage = message
        }
        if (!TextUtils.isEmpty(speakMessage) && speakMessage!!.length <= 60) {
            mSpeechSynthesizer!!.speak(speakMessage)
        } else {
            startDiscern(TextUtils.isEmpty(aid))
        }
    }

    /**
     * 收起软键盘，华为安全键盘弹起后会遮挡toast
     */
    private fun hideInputWindow() {
        val manager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
        manager.hideSoftInputFromWindow(
            currentFocus!!.windowToken,
            InputMethodManager.HIDE_NOT_ALWAYS
        )
    }

    /**
     * 打开软键盘
     */
    private fun showInputWindow() {
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
        edMsg?.isFocusable = true
        edMsg?.isFocusableInTouchMode = true
        edMsg?.requestFocus()
        edMsg?.findFocus()
        val manager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
        manager.showSoftInput(edMsg, 0)
    }

    /**
     * 取消本次识别，取消后将立即停止不会返回识别结果
     */
    private fun cancelDiscern(isListener: Boolean) {
        try {
            asr?.send(SpeechConstant.ASR_CANCEL, null, null, 0, 0)
            showDiscernLayout(isListener)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onClick(v: View) {
        if (v.id == R.id.sendMsg) {
            TXReportManager.getInstance().app_jhapp_ai_assistant_use("文字", edMsg?.text.toString())
            sendMessage(edMsg?.text.toString())
            edMsg?.setText("")
        } else if (v.id == R.id.btn_voice) {
            if (PermissionUtils.checkPermission(this, Manifest.permission.RECORD_AUDIO)) {
                edMsg?.setText("")
                bottom?.visibility = View.GONE
                hideInputWindow()
//                mHandler.removeCallbacksAndMessages(null)
                stopAudio()
                cancelDiscern(false)
                stopDiscern(false)
                if (mediaPlayer != null) {
                    mediaPlayer?.pause()
                }
                startDiscern(true)
            } else {
                ToastUtil.showCustomView(this, "请打开麦克风权限")
            }
        } else if (v.id == R.id.iv_key_board) {
            cancelDiscern(false)
            stopDiscern(false)
            input_tx?.visibility = View.GONE
            bottom?.visibility = View.VISIBLE
            showInputWindow()
        } else if (v.id == R.id.mic_img) {
            startDiscern(true)
        } else if (v.id == R.id.mic_img_log) {
//            cancelDiscern(false)
            stopDiscern(false)
        }
    }

    private fun sendMessage(text: String?) {
        hideInputWindow()
        if ("播报最新新闻" == text) {
            //type = 1  title = APP   id = 385345
            val articleItem = ArticleItem()
            articleItem.setType(1)
            articleItem.title = "APP"
            articleItem.id = 385345
            val intent = Intent()
            intent.setClassName(
                this,
                "com.mediacloud.app.newsmodule.activity.ImageTextDetailActivity2"
            )
            intent.putExtra("type", 1)
            intent.putExtra("data", articleItem)
            startActivity(intent)
            finish()
            return
        }
        //    private ArrayList<AiAssistantData> dataList;
        if (TextUtils.isEmpty(text)) {
            ToastUtil.show(this, "请填写问题")
            return
        }
        val aiAssistantData = AiAssistantData()
        aiAssistantData.msg = text
        aiAssistantData.type = RIGHT_CHAT
        mAdapter?.addData(aiAssistantData)
        recyclerView?.scrollToPosition(mAdapter!!.itemCount - 1)
        val isPaper = MMKV.defaultMMKV().getBoolean(XKey.IS_JUNMEI_PAPER, false)
        AiAssistantApi.getSpiderCmsApiJson(this) /*.chatbot("3b592c75ee1974509679e28ec2b4fce4", text, !TextUtils.isEmpty(mSessionId) ? mSessionId : "")*/
            .chatbot(
                DeviceInfo.getDeviceInfo(this).deviceInfo4Server.device_flag,
                text,
                getString(R.string.tenantid),
                if (isPaper) 1 else 0,
                map
            )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<JSONObject> {
                override fun onSubscribe(d: Disposable) {}
                override fun onNext(jsonObject: JSONObject) {
                    stopAudio()
                    stopDiscern(false)
                    if (mediaPlayer != null && mediaPlayer!!.isPlaying) {
                        mediaPlayer?.pause()
                    }
                    val data = jsonObject.optJSONObject("data") ?: return
                    val aiAssistantData =
                        GsonUtils.fromJson(data.toString(), AiAssistantData::class.java)
                    answerType = aiAssistantData.answerType
                    message = aiAssistantData.content
                    readSize = aiAssistantData.readSize
                    aid = aiAssistantData.aid
                    when (answerType) {
                        "close" -> finish()
                        "text", "richText" -> {
                            aiAssistantData.type = LEFT_CHAT
                            mAdapter?.addData(aiAssistantData)
                            recyclerView?.scrollToPosition(mAdapter!!.itemCount - 1)
                            active = ""
                            speak()
                        }
                        "redirectH5" -> {
                            input_tx?.visibility = View.GONE
                            val split = aiAssistantData.active.split("\\|".toRegex())
                                .dropLastWhile { it.isEmpty() }
                                .toTypedArray()
                            if (split.isNotEmpty()) {
                                val intent = Intent()
                                intent.setClassName(
                                    this@AIAssistantActivity,
                                    "com.mediacloud.app.newsmodule.activity.WebViewPageActivity"
                                )
                                val builder = Uri.Builder()
                                builder.appendQueryParameter("title", split[0])
                                builder.appendQueryParameter("url", split[1])
                                val articleItem = ArticleItem()
                                articleItem.title = split[0]
                                articleItem.url = split[1]
                                intent.putExtra("data", articleItem)
                                intent.putExtra("title", split[0])
                                intent.data = builder.build()
                                startActivity(intent)
                            }
                        }
                        "redirectPage" -> {
                            active = aiAssistantData.active
                            if (active!!.contains("|")) {
                                val intentActivity = Intent()
                                EventBus.getDefault().post(IntentAppHomeEvent(active))
                                intentActivity.setClassName(
                                    this@AIAssistantActivity,
                                    "com.mediacloud.app.nav2.AppHome21Style"
                                )
                                startActivity(intentActivity)
                            } else {
                                val intentOpen = Intent()
                                if (active == "设置") {
                                    intentOpen.setClassName(
                                        this@AIAssistantActivity,
                                        "com.mediacloud.app.appfactory.activity.setting.SettingHomeNewActivity"
                                    )
                                } else if (active == "意见反馈") {
                                    if (AppFactoryGlobalConfig.ServerAppConfigInfo.OtherConfig.feedbackLogin) {
                                        if (UserInfo.isLogin(this@AIAssistantActivity)) {
                                            intentOpen.setClassName(
                                                this@AIAssistantActivity,
                                                "com.mediacloud.app.appfactory.activity.setting.SuggestionHelpActivity"
                                            )
                                        } else {
                                            ToastUtil.show(this@AIAssistantActivity, "请先登录")
                                            return
                                        }
                                    } else {
                                        intentOpen.setClassName(
                                            this@AIAssistantActivity,
                                            "com.mediacloud.app.appfactory.activity.setting.SuggestionHelpActivity"
                                        )
                                    }
                                } else if (active == "扫一扫") {
                                    intentOpen.setClassName(
                                        this@AIAssistantActivity,
                                        ModuleReferenceConfig.ScanForQRActivity
                                    )
                                }
                                startActivityForResult(intentOpen, 0)
                            }
                        }
                        "search" -> {
                            search = aiAssistantData.search
                            //                                    if (aiAssistantData.getActive().equals("VIDEO")) {
//                                        active = "视频";
//                                    } else if (aiAssistantData.getActive().equals("ARTICLE") || aiAssistantData.getActive().equals("INFORMATION")) {
//                                        active = "资讯";
//                                    } else if (aiAssistantData.getActive().equals("LIVE")) {
//                                        active = "直播";
//                                    }
                            active = aiAssistantData.active
                            val intent = Intent()
                            intent.setClassName(
                                this@AIAssistantActivity,
                                ModuleReferenceConfig.SearchActivity
                            )
                            intent.putExtra("behavior", active)
                            intent.putExtra("SEARCH_KEY", search)
                            intent.putExtra("SEARCH_NOW", "now")
                            intent.putExtra("isPolitics", false)
                            startActivityForResult(intent, 0)
                        }
                        "hotArticle" -> {
                            aiAssistantData.type = LEFT_CHAT_ARTICLE
                            mAdapter?.addData(aiAssistantData)
                            recyclerView?.scrollToPosition(mAdapter!!.itemCount - 1)
                            active = ""
                            speak()
                        }
                        "voice" -> {
                            aiAssistantData.type = LEFT_CHAT_VOICE
                            mAdapter?.addData(aiAssistantData)
                            recyclerView?.scrollToPosition(mAdapter!!.itemCount - 1)
                            active = ""
                            if (aiAssistantData.voice != null && !TextUtils.isEmpty(aiAssistantData.voice.url)) {
                                stopAudio()
                                setData(aiAssistantData.voice.url)
                            }
                        }
                        "newspaper" -> if (aiAssistantData.newspaper != null) {
                            val intentActivity = Intent()
                            intentActivity.setClassName(
                                this@AIAssistantActivity,
                                "com.mediacloud.app.nav2.AppHome21Style"
                            )
                            startActivity(intentActivity)
                            val newspaper = aiAssistantData.newspaper
                            if (newspaper != null) {
                                if (isPaper) {
                                    if (newspaper.paperActive != null) {
                                        val paperActive = newspaper.paperActive
                                        if (!TextUtils.isEmpty(paperActive.dateActive)) {
                                            EventBus.getDefault()
                                                .post(ActionDateActive(paperActive.dateActive))
                                        } else if (!TextUtils.isEmpty(paperActive.editionActive)) {
                                            EventBus.getDefault()
                                                .post(ActionEditionActive(paperActive.editionActive))
                                        } else if (!TextUtils.isEmpty(paperActive.partActive)) {
                                            EventBus.getDefault()
                                                .post(ActionPartActive(paperActive.partActive))
                                        }
                                    }
                                    if (newspaper.paperDetail != null) {
                                        val paperDetail = newspaper.paperDetail
                                        val p = PaperDetailBean()
                                        p.date = paperDetail.date
                                        p.editionNumber = paperDetail.editionNumber
                                        p.partNumber = paperDetail.partNumber
                                        p.editionName = paperDetail.editionName
                                        EventBus.getDefault().post(p)
                                    }
                                } else {
                                    if (newspaper.paperDetail != null) {
                                        val paperDetail = newspaper.paperDetail
                                        MMKV.defaultMMKV()
                                            .putString(XKey.OPEN_PAPER_DATE, paperDetail.date)
                                        MMKV.defaultMMKV()
                                            .putString(
                                                XKey.OPEN_EDITION_DATE,
                                                paperDetail.editionNumber
                                            )
                                        MMKV.defaultMMKV()
                                            .putString(
                                                XKey.OPEN_EDITION_NAME_DATE,
                                                paperDetail.editionName
                                            )
                                        MMKV.defaultMMKV()
                                            .putString(XKey.OPEN_PART_DATE, paperDetail.partNumber)
                                        MMKV.defaultMMKV()
                                            .putString(XKey.OPEN_PAPER_NAME, paperDetail.paperName)
                                        if (packageName == "com.test.paytocloud.huaqiyun.project") {
                                            EventBus.getDefault()
                                                .postSticky(IntentAppHomeEvent("首页|解放军报", true))
                                        } else {
                                            EventBus.getDefault()
                                                .postSticky(IntentAppHomeEvent("军媒|解放军报", true))
                                        }
                                    }
                                }
                            }

                        }
                        else -> {
                            toastCenter(this@AIAssistantActivity, "请稍候重试")
                        }
                    }
                }

                override fun onError(e: Throwable) {
                    toastCenter(this@AIAssistantActivity, "请稍候重试")
                }

                override fun onComplete() {}
            })
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (TextUtils.isEmpty(active)) {
            return
        }
        val aiAssistantData = AiAssistantData()
        aiAssistantData.type = LEFT_CHAT
        if (answerType == "search") {
            aiAssistantData.msg = search
            aiAssistantData.answerType = answerType
        }
        if (TextUtils.isEmpty(aiAssistantData.msg)) {
            aiAssistantData.content = "报告，完成任务！"
        } else {
            aiAssistantData.content = "任务完成，请查阅！"
        }
        aiAssistantData.active = active
        mAdapter?.addData(aiAssistantData)
        recyclerView?.scrollToPosition(mAdapter!!.itemCount - 1)
    }

    override fun getContent_show_top_color(): String {
        topView?.setBackgroundColor(Color.WHITE)
        return "#333333"
    }

    override fun getStatusBarColor(): Int {
        return Color.WHITE
    }

    /**
     * 点击停止按钮
     * 基于SDK集成4.1 发送停止事件
     */
    private fun stopDiscern(isListener: Boolean) {
        printLog("停止识别：ASR_STOP")
        if (asr != null) {
            asr?.send(SpeechConstant.ASR_STOP, null, null, 0, 0)
            showDiscernLayout(isListener)
        }
    }

    private fun stopDiscern() {
        printLog("停止识别：ASR_STOP")
        if (asr != null) {
            asr?.send(SpeechConstant.ASR_STOP, null, null, 0, 0)
        }
    }

    private fun stopAudio() {
        if (mSpeechSynthesizer != null) {
            mSpeechSynthesizer?.stop()
        }
    }

    override fun onBackPressed() {
        if (input_tx?.visibility == View.VISIBLE) {
            input_tx?.visibility = View.GONE
            stopDiscern(false)
            stopAudio()
            finish()
            return
        }
        super.onBackPressed()
    }

    override fun onPause() {
        super.onPause()
        audioFlag = false
        stopAudio()
        stopDiscern(false)
        MMKV.defaultMMKV().putBoolean(XKey.FULL_SCREEN, false)
    }

    override fun onResume() {
        super.onResume()
        audioFlag = true
    }

    override fun onDestroy() {
        checkDestroy = true
        MMKV.defaultMMKV().putBoolean(XKey.FULL_SCREEN, false)
        hideInputWindow()
        mAudioManager?.abandonAudioFocus(focusChangeListener)
        if (mediaPlayer != null) {
            mediaPlayer?.pause()
            mediaPlayer?.stop()
            mediaPlayer?.release()
            mediaPlayer = null
        }
        stopDiscern()
        stopAudio()
        asr?.unregisterListener(this)
        asr = null
        mSpeechSynthesizer = null
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        super.onDestroy()
    }

    private val focusChangeListener = AudioManager.OnAudioFocusChangeListener { i ->
        if (audioFlag) {
            return@OnAudioFocusChangeListener
        }
        if (i == -1 || i == -2) {
            if (mediaPlayer!!.isPlaying) {
                mediaPlayer?.pause()
            }
        }
    }

    private fun setData(url: String?) {
        mAudioManager?.requestAudioFocus(
            focusChangeListener,
            AudioManager.STREAM_MUSIC,
            AudioManager.AUDIOFOCUS_GAIN
        )
        if (url != null) {
            if (url == this.url) {
                if (mediaPlayer!!.isPlaying) {
                    mediaPlayer?.pause()
                } else {
                    mediaPlayer?.start()
                }
                return
            }
            this.url = url
            try {
                mediaPlayer?.stop()
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                mediaPlayer = null
            }
            mediaPlayer = PlayerTools.createIJKPlayer(false)
            //  checkNetType(context)
            mediaPlayer?.isLooping = false
            mediaPlayer?.setVolume(1f, 1f)
            // mediaPlayer?.setDisplay(surfaceView.holder)
            try {
                mediaPlayer?.dataSource = url
                mediaPlayer?.prepareAsync()
                mediaPlayer?.start()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        } else {
            this.url = null
            if (mediaPlayer!!.isPlaying) {
                mediaPlayer?.pause()
            }
        }
    }
}